package cn.crc.web.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 基础功能测试_25.4.16
 */
public class TestStream6 {
    public static void main(String[] args) {//https://bbs.huaweicloud.com/blogs/444154
        TestStream6.test2映射成流();
        TestStream6.test2去除重复();
        TestStream6.test2排序();
        //TestStream6.test2调试();
        //TestStream6.test2组合起来();
        TestStream6.test6收集器();
        TestStream6.test6匹配();//发现一个实用
        TestStream6.test6查找();
        //TestStream6.test6计数();
        //TestStream6.test6并行流();
    }

    /**
     * 1. flatMap
     * flatMap操作与map类似，但它允许你将流中的每个元素映射成一个流，然后将这些流“扁平化”为一个流。这在处理嵌套集合时特别有用
     */
    private static void test2映射成流(){
        List<List<String>> listOfLists = Arrays.asList(Arrays.asList("a", "b"), Arrays.asList("c", "d"));
        List<String> flatList = listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
        System.out.println("映射成流："+flatList);
    }
    //2.distinct操作返回由该流中不同元素组成的流（根据Object.equals(Object)确定）。它常用于去除流中的重复元素
    private static void test2去除重复(){
        List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
        List<Integer> uniqueNumbers = numbers.stream().distinct().collect(Collectors.toList());
        System.out.println("去除重复："+uniqueNumbers);
    }
    //3.sorted操作返回一个排序后的流。它可以接受一个Comparator来定义排序规则，或者根据元素的自然顺序进行排序
    private static void test2排序(){
        List<String> strings = Arrays.asList("banana", "apple", "cherry");
        List<String> sortedStrings = strings.stream().sorted().collect(Collectors.toList());
        System.out.println("排序："+sortedStrings);
    }
    //4.peek操作主要用于调试目的，它允许你在流的每个元素上执行操作（如打印日志），但不改变流本身。
    private static void test2调试(){
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        long num= numbers.stream().peek(System.out::println).count();
        System.out.println("调试："+num);
    }
    //5.reduce操作可以将流中的元素组合起来，返回一个单一的结果。它通常用于数值计算，如求和、求积等
    private static void test2组合起来(){
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream().reduce(0, Integer::sum);
        System.out.println("组合起来："+sum);
    }

    //6.collect与自定义收集器
    //collect(Collectors.toList())和collect(Collectors.toSet())是常见的用法，但Collectors类还提供了更多自定义收集器的方法，如toMap、groupingBy等
    private static void test6收集器(){
        List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
        List<Integer> uniqueNumbers = numbers.stream().distinct().collect(Collectors.toList());
        System.out.println("收集器："+uniqueNumbers);
    }
    //7. anyMatch、allMatch、noneMatch
    //这些操作允许你对流中的元素进行布尔条件测试，并返回一个布尔值。anyMatch检查流中是否存在至少一个匹配元素，allMatch检查所有元素是否匹配，而noneMatch检查是否没有元素匹配
    private static void test6匹配(){
        List<String> strings = Arrays.asList("apple", "banana", "cherry");
        boolean hasBanana = strings.stream().anyMatch(s -> s.startsWith("b"));//只要流中一个元素满足条件就返回true
        boolean has3 = strings.stream().allMatch(s -> s.toLowerCase().equals("b"));//只要流中所有元素满足条件才返回true
        boolean has5 = strings.stream().noneMatch(s -> s.toLowerCase().equals("dog"));//如果流中没有元素满足条件则返回true
        System.out.println("匹配："+hasBanana+";"+has3+";"+has5);
    }
    //8. findFirst和findAny
    //这些操作用于从流中获取第一个元素或任意元素（如果存在）。findFirst通常用于有序流，而findAny在并行流中可能更有效。
    private static void test6查找(){
        List<String> strings = Arrays.asList("apple", "banana", "cherry");
        Optional<String> firstString = strings.stream().findFirst();
        Optional<String> findAny = strings.stream().findAny();
        System.out.println("查找："+firstString+";"+findAny);
    }
    //9.count操作返回流中元素的数量。虽然这可以通过collect(Collectors.counting())实现，但count方法通常更高效
    private static void test6计数(){
        List<String> strings = Arrays.asList("apple", "banana", "cherry");
        long count = strings.stream().count();
        System.out.println("计数："+count);
    }
    //10. 并行流，通过将流转换为并行流，可以利用多核处理器加速处理。这通常通过调用parallelStream()方法实现
    private static void test6并行流(){
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.parallelStream().reduce(0, Integer::sum);
        System.out.println("并行流："+sum);
    }
}
